/// <reference path="./script.ts" />
namespace FIREFLYX {
    export class CameraHoverScript extends Script {
        private _lastMouseX: number;
        private _lastMouseY: number;
        private _mouseDown = false;
        private _panAngle: number = 0;
        private _panRad: number = 0;
        private _tiltAngle: number = 0;
        private _tiltRad: number = 0;

        /** 观察点 */
        public lookAtPoint: Vector3 = new Vector3(0, 0, 0);
        /** 观察目标 */
        public lookAtTarget: Transform;
        /** 观察距离 */
        public distance: number = 30;
        public minPanAngle: number = -Infinity;
        public maxPanAngle: number = Infinity;
        public minTileAngle: number = -89;
        public maxTileAngle: number = 89;
        public scaleSpeed: number = 2;

        /** 平移角度 */
        public set panAngle(value: number) {
            this._panAngle = Math.max(this.minPanAngle, Math.min(this.maxPanAngle, value));
            this._panRad = this._panAngle * Math.PI / 180;
        }

        public get panAngle(): number {
            return this._panAngle;
        }

        /** 仰角角度 */
        public set tiltAngle(value: number) {
            this._tiltAngle = Math.max(this.minTileAngle, Math.min(this.maxTileAngle, value));
            this._tiltRad = this._tiltAngle * Math.PI / 180;
        }

        public get tiltAngle(): number {
            return this._tiltAngle;
        }

        public start() {
            //事件注册
            GlobalEventManager.Instance.addListener("pointDown", this.onPointDown, this);
            GlobalEventManager.Instance.addListener("pointUp", this.onPointUp, this);
            GlobalEventManager.Instance.addListener("pointMove", this.onPointMove, this);
            GlobalEventManager.Instance.addListener("mousewheel", this.onWheel, this);

        }

        private cupTargetV3 = new Vector3();
        public update(delta: number) {
            let distanceX = this.distance * Math.sin(this._panRad) * Math.cos(this._tiltRad);
            let distanceY = this.distance * (this._tiltRad == 0 ? 0 : Math.sin(this._tiltRad));
            let distanceZ = this.distance * Math.cos(this._panRad) * Math.cos(this._tiltRad);

            if (this.lookAtTarget) {
                this.cupTargetV3.copyFrom(this.lookAtTarget.position);
                // gd3d.math.vec3Clone(this.lookAtTarget.getWorldTranslate(),this.cupTargetV3);
            } else {
                this.cupTargetV3.copyFrom(this.lookAtPoint);
            }

            //更新位置
            if (!this.entity) return;
            let eyeTran = this.entity.transform;
            let ePos = eyeTran.position;
            ePos.set(this.cupTargetV3.x + distanceX, this.cupTargetV3.y + distanceY, this.cupTargetV3.z + distanceZ);
            eyeTran.position = ePos;

            //看向目标
            this.entity.transform.lookatPoint(this.cupTargetV3);
        }

        private onPointDown(e: Vector2) {
            this._mouseDown = true;
            this._lastMouseX = e.x;
            this._lastMouseY = e.y;
        }

        private onPointUp() {
            this._mouseDown = false;
        }

        private onPointMove(e: Vector2) {
            if (!this._mouseDown) return;
            let moveX = e.x - this._lastMouseX;
            let moveY = e.y - this._lastMouseY;

            this.panAngle += moveX;
            this.tiltAngle += moveY;

            this._lastMouseX = e.x;
            this._lastMouseY = e.y;
        }

        private onWheel(e: WheelEvent) {
            this.distance = Math.max(this.distance - this.getDetal(e) * this.scaleSpeed, 1);
        }

        private getDetal(ev: WheelEvent) {
            let delta = 0;
            if (ev.detail) {
                delta = -1 * ev.detail;
            } else if ((ev as any).wheelDelta) {
                delta = (ev as any).wheelDelta / 120;
            } else if (ev.DOM_DELTA_PIXEL) {
                delta = ev.DOM_DELTA_PIXEL / 120;
            }
            return delta;
        }

        public remove() {
            //事件注销
            GlobalEventManager.Instance.removeListener("pointDown", this.onPointDown, this);
            GlobalEventManager.Instance.removeListener("pointUp", this.onPointUp, this);
            GlobalEventManager.Instance.removeListener("pointMove", this.onPointMove, this);
            GlobalEventManager.Instance.removeListener("mousewheel", this.onWheel, this);

        }

    }
}